package gui;

import collector.Chain;
import collector.Collector;
import collector.Configuration;
import collector.FileObj;
import console.App;

import java.util.ArrayList;

/**
 * Uses a SwingWorker to perform a time-consuming (and utterly fake) task.
 */

/*
 * LongTask.java is used by:
 *   ProgressBarDemo.java
 *   ProgressBarDemo2.java
 *   ProgressMonitorDemo
 */
public class LongTask {
    //share data
    public ChainTableModel ctm;
    public FileTableModel ftm;
    public ArrayList<Chain> chains;

    private int lengthOfTask;
    private int current = 1;
    private boolean done = false;
    private boolean canceled = false;
    private String statMessage;
    public StringBuffer errorMess;
    public ArrayList<FileObj> files;
    public ArrayList<FileObj> containDupFiles;
    LongTask lt = this;
    private Collector collector;
    private final Configuration configuration;

    public LongTask(Configuration configuration, ArrayList<FileObj> files) {
        this.configuration = configuration;
        //Compute length of task...
        //In a real program, this would figure out
        //the number of bytes to read or whatever.
        lengthOfTask = 100;
        this.files = files;
    }

    /**
     * Called from ProgressBarDemo to start the task.
     */

    public void go() {
        final SwingWorker worker = new SwingWorker() {
            public Object construct() {
                current = 0;
                done = false;
                canceled = false;
                return new ActualTask();
            }
        };
        worker.start();
    }

// --Commented out by Inspection START (4/30/07 5:21 PM):
//    /**
//     * Called from ProgressBarDemo to find out how much work needs
//     * to be done.
//     *
//     * @return total amount of work
//     */
//    public int getLengthOfTask() {
//        return lengthOfTask;
//    }
// --Commented out by Inspection STOP (4/30/07 5:21 PM)

    /**
     * Called from ProgressBarDemo to find out how much has been done.
     *
     * @return current amount of work
     */
    public int getCurrent() {
        return current;
    }

    public void setCurrent(int current) {
        this.current = current;
    }

    public void stop() {
        canceled = true;
    }

    /**
     * Called from ProgressBarDemo to find out if the task has completed.
     *
     * @return true if the task is complete
     */
    public boolean isDone() {
        return done;
    }

    /**
     * @return the most recent status message, or null
     *         if there is no current status message.
     */
    public String getMessage() {
        return statMessage;
    }

    public void setStatMessage(String statMessage) {
        this.statMessage = statMessage;
    }

    public void setCanceled(boolean canceled) {
        this.canceled = canceled;
    }

    public boolean isCanceled() {
        return canceled;
    }


    public Collector getCollector() {
        return collector;
    }

    /**
     * The actual long running task.  This runs in a SwingWorker thread.
     */
    class ActualTask {
        ActualTask() {
            while (!canceled && !done) {
                try {
                    errorMess = new StringBuffer();
                    collector = new Collector(lt, files, configuration);
                    collector.findDuplicatedCode();
                    chains = collector.getChains();
                    ctm = new ChainTableModel(collector, chains);
                    //refine the file list to remove the file that contain no duplicated chunk
                    containDupFiles = App.getOnlyFilesHasDup(files);
                    ftm = new FileTableModel(containDupFiles);

                    done = true;
                    current = lengthOfTask;
                    statMessage = "Completed " + current +
                            " out of " + lengthOfTask + ".";
                } catch (Exception e) {
                    e.printStackTrace();
                    errorMess.insert(0, "Cannot finish dectecting\n");
                    statMessage = errorMess.toString().intern();
                    errorMess.setLength(0);
                    canceled = true;
                }
            }
        }
    }
}
